import { FloatButton, FloatButtonGroupProps } from "antd";
import React, { Context, createContext, Dispatch, Fragment, PropsWithChildren, ReactNode, SetStateAction, useContext, useEffect, useMemo, useState } from "react";

export namespace FloatGroup {
  export interface RenderButton { (): ReactNode }
  export interface ContextValue {
    adopted_children: RenderButton[],
    set_children: Dispatch<SetStateAction<RenderButton[]>>,
    add_children: (fn: RenderButton[]) => void,
    del_children: (fn: RenderButton[]) => void
  }
}
const init_ctx_value: FloatGroup.ContextValue = {
  adopted_children: [],
  set_children: () => null,
  add_children: () => { },
  del_children: () => { }
}
const _create_ctx = () => createContext({ ...init_ctx_value });
const _global_ctx = _create_ctx();

export interface IFloatGroupProps extends FloatButtonGroupProps {
  ctx?: Context<FloatGroup.ContextValue>
}
export function FloatGroup(props: IFloatGroupProps) {
  const { children, ctx = _global_ctx, ..._p } = props;
  const { adopted_children } = useContext(ctx);
  return (
    <FloatButton.Group {..._p}>
      {adopted_children.map((fn, idx) => {
        const inner = fn()
        return inner ? <Fragment key={idx}> {inner} </Fragment> : null
      })}
      {children}
    </FloatButton.Group>
  )
}
FloatGroup.use = (ctx: Context<FloatGroup.ContextValue> = _global_ctx) => useContext(ctx)
FloatGroup.Provider = function (props: PropsWithChildren & { ctx?: Context<FloatGroup.ContextValue> }) {
  const { ctx = _global_ctx, ..._p } = props;
  const [adopted_children, set_children] = useState<(() => ReactNode)[]>([])
  const context_value = useMemo<FloatGroup.ContextValue>(() => {
    const ret: FloatGroup.ContextValue = {
      adopted_children,
      set_children,
      add_children: targets => set_children(prev => [...prev, ...targets]),
      del_children: targets => set_children(prev => prev.filter(v => targets.indexOf(v) < 0)),
    }
    return ret;
  }, [adopted_children, set_children])
  return <ctx.Provider {..._p} value={context_value} />
}